package com.majun.web;


import com.amazonaws.services.s3.model.ObjectMetadata;
import com.majun.file.AwzS3Util;
import org.apache.commons.io.IOUtils;
import org.apache.tika.Tika;
import org.apache.tika.io.TikaInputStream;
import org.apache.tika.metadata.Metadata;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StopWatch;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.FileNameMap;
import java.net.URL;
import java.net.URLConnection;
import java.text.MessageFormat;


@RestController
@RequestMapping("/aws")
public class S3Controller {

    private final Logger log = LoggerFactory.getLogger(getClass());

    @Autowired
    private AwzS3Util awzS3Util;

    @PostMapping(value = "/upload")
    public ResponseEntity uploadObject(MultipartFile file, String bucket) {
        try {
            awzS3Util.upload(file, bucket);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new ResponseEntity("上传成功!", HttpStatus.OK);
    }

    @GetMapping(value = "/download/{bucket}/{fileName}")
    public void downloadObject(@PathVariable("bucket")String bucket, @PathVariable("fileName")String fileName, HttpServletResponse response ) {
        try {
            awzS3Util.downloadByName(bucket, fileName, response);
//            awzS3Util.downloadFile(bucket, fileName, response);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ;
    }

    //    @PostMapping(value = "/getFileInfo")
    @GetMapping(value = "/getFileInfo")
    public ObjectMetadata getFileInfo(String bucket, String fileName) {
        return awzS3Util.getFileInfo(bucket, fileName);
    }

    @GetMapping(value = "/createUrl")
    public String createUrl(String bucket, String fileName) {
        return awzS3Util.generatePresignedUrl(bucket, fileName);
    }

    @GetMapping(value = "/getUrl")
    public String getUrl(String bucket, String fileName) {
        return awzS3Util.getUrl(bucket, fileName);
    }

    @GetMapping(value = "/getPreUrl")
    public void getPreUrl(String bucket, String fileName, HttpServletResponse response) {
        String url = awzS3Util.generatePresignedUrl(bucket, fileName);
        try {
            response.sendRedirect(url);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @GetMapping(value = "/uploadtest")
    public void uploadtest(String bucket) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start("uploadtest");
        String filePath ="D:\\tmp\\heapdump.sql";
        File file = new File(filePath);
        awzS3Util.uploadLocal(bucket, file);
        stopWatch.stop();
        System.err.println("uploadtest==="+stopWatch.getTotalTimeMillis());
    }

    @GetMapping(value = "/deleteFile")
    public boolean deleteFile(String bucket, String fileName) {
        return awzS3Util.deleteFile(bucket, fileName);
    }

    @GetMapping(value = "/exist")
    public boolean exist(String bucket, String fileName) {
        return awzS3Util.exist(bucket, fileName);
    }


    @GetMapping(value = "/copy")
    public boolean copy(String bucket, String fileName, String newKey) {
        return awzS3Util.copyFile(bucket, fileName, newKey);
    }


    @GetMapping(value = "/list")
    public boolean listDelimiter(String bucket, String prefix) {
        awzS3Util.listDelimiter(bucket, prefix);

        return true;
    }

    @GetMapping(value = "/uploadbig")
    public void bigFileListShardingUpload() {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        String bucketName = "test";
        String filePath ="D:\\tmp\\heapdump.sql";
        String fileName = "dump.hpfo";
        File file = new File(filePath);
        awzS3Util.bigFileListShardingUpload(bucketName, fileName, file);
        stopWatch.stop();
        System.err.println("uploadbig==="+stopWatch.getTotalTimeMillis());
    }

    @GetMapping(value = "/uploadhigh")
    public void highLevelMultipartUpload() {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        String bucketName = "test";
        String filePath ="D:\\tmp\\heapdump.sql";
        String fileName = "highdump.hfop";
        File file = new File(filePath);
        try {
            awzS3Util.highLevelMultipartUpload(bucketName, fileName, file);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        stopWatch.stop();
        System.err.println("uploadbig==="+stopWatch.getTotalTimeMillis());
    }




    @GetMapping(value = "/writeFile")
    public void writeFileToResp(HttpServletResponse response) {
        InputStream inputStream = null;
        try {
            String path = "http://10.154.140.243:8080/fssc/extapi/bybo/download?attachmentId=group1/M00/01/0F/CpqM82aYuQ6ALsa4AACSETt9Tog56.xlsx&attachmentName=医疗对接健投抵扣认证-用例.xlsx";
            URL url = new URL(path);
            URLConnection conn = url.openConnection();
            inputStream = conn.getInputStream();
            byte[] buf = new byte[1024 * 10];
            ServletOutputStream outputStream = response.getOutputStream();
            int readLength;
            while (((readLength = inputStream.read(buf)) != -1)) {
                outputStream.write(buf, 0, readLength);
            }
            outputStream.flush();
        } catch (Exception e) {
            log.warn(e.getMessage(), e);
            throw new RuntimeException("io exception " + e.getMessage());
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
            } catch (IOException e) {
                log.error(e.getMessage(), e);
            }
        }
    }

    @GetMapping(value = "/detect")
    public String whenUsingTika() throws IOException {
//        File file = new File("D:\\tmp\\团险核心-新手指引.ppt");
//        File file = new File("D:\\tmp\\团险核心-新手指引.pptx");
        File file = new File("D:\\tmp\\文件复制--复制容器内的文件到本地.docx");
//        File file = new File("D:\\tmp\\文件复制--复制容器内的文件到本地.doc");
        String mimeType = getMimeType(file);
        System.err.println("mimeType=="+mimeType);
//        System.err.println(mimeType);
//
//        String mimeType2 = tika.detect(file2);
//        System.err.println(mimeType2);

        byte[] fileBytes = IOUtils.toByteArray(new FileInputStream(file));
        FileInputStream fileInputStream = new FileInputStream(file);
        String mimeType3 = getMimeType(fileBytes, file);

        System.out.println("mimeType3=="+mimeType3);
        System.out.println(file.getName());

        FileNameMap fileNameMap = URLConnection.getFileNameMap();
        String contentTypeFor = fileNameMap.getContentTypeFor(file.getName());
        System.out.println("contentTypeFor=="+contentTypeFor);
        return mimeType3;
    }

    private static String getMimeType(File file) throws IOException {
        Tika tika = new Tika();
        String mimeType = tika.detect(file);
        return mimeType;
    }

    private static String getMimeType(byte[] fileBytes, File file) throws IOException {
        Tika tika = new Tika();
        Metadata metadata = new Metadata();
        TikaInputStream tikaInputStream = TikaInputStream.get(fileBytes, metadata);
        metadata.set("resourceName", file.getName());
        metadata.set("Content-Length", Long.toString(file.length()));
        String mimeType3 = tika.detect(tikaInputStream, metadata);
        return mimeType3;
    }

    @GetMapping(value = "/error")
    public void error() {
        try {
            int i = 1 / 0;
        } catch (Exception e) {
//            String formatMsg = MessageFormat.format("error堆栈信息：{0},{1}", "参数0", "参数2test");
            String formatMsg = MessageFormat.format("error堆栈信息:",null);
            log.error(formatMsg, e);
        }
    }

}